package com.raymond.thread.manager.circulation;

import com.raymond.thread.manager.BaseThread;
import com.raymond.thread.manager.StaticValues;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 循环线程任务
 * 重写init()方法,线程开始运行时,运行一次,异常线程直接退出
 * 实现execute()方法,就会一直执行此任务,返回是否需要休眠,true需要休眠,false直接运行
 * 休眠时间sleep,默认一秒执行一次,通过setSleep(long sleep)可以设置休眠时间,单位毫秒
 * 重写after()方法,线程退出的时候运行
 * @author :  raymond
 * @version :  V1.0
 * @date :  2020-09-11 14:11
 */
public abstract class BaseCirculationThread extends BaseThread {
    private static final Logger logger = LoggerFactory.getLogger(BaseCirculationThread.class);
    /**线程休眠时间(单位毫秒)**/
    private long sleep = 1000;
    /**当前线程退出标识**/
    private boolean currentThreadIsExit = false;

    @Override
    public final void run() {
        super.run();
        init();
        while (!StaticValues.IS_EXIT && !currentThreadIsExit) {
            try {
                if (StaticValues.IS_STOP || execute()) {
                    Thread.sleep(sleep);
                }
            } catch (Exception e) {
                logger.error("循环线程异常,{}", getName(), e);
                try {
                    Thread.sleep(sleep);
                } catch (InterruptedException ex) {
                    logger.error("循环线程异常,{}", getName(), e);
                }
            }
        }
        after();
    }

    /**
     * 初始化方法,当前线程启动运行一次
     */
    protected void init(){
        logger.info("循环线程已启动,{}", getName());
    }

    /**
     * 线程关闭运行的方法
     */
    protected void after() {
        logger.info("循环线程已关闭,{}", getName());
    }
    /**
     * 循环任务
     * @return 是否需要休眠,true需要休眠后运行,false直接再次运行
     */
    protected abstract boolean execute();

    /**
     * 设置休眠时间(单位毫秒)
     * @param sleep 休眠时间(单位毫秒)
     */
    public final void setSleep(long sleep) {
        this.sleep = sleep;
    }

    /**
     * 退出当前循环线程
     * 调用此方法后不再运行循环任务
     */
    public final void currentThreadExit() {
        this.currentThreadIsExit = true;
    }
}
